home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / network.swg < prev    next >
Text File  |  1994-09-22  |  38KB  |  2 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00006                                                                           1      08-24-9413:48ALL                      OLAF BARTELT             Netware Encrypted Login  SWAG9408    ┘Y┬╛    109    ,î   π{$R+,V-}ππ{ This program will prompt for a server, login id and password.  All }π{ input will be echoed to the screen!                                }ππPROGRAM LOGON;ππUSESπ  Dos,π  Crt;ππCONSTπ  NET_USER         = 1;π  USER_GROUP       = 2;π  FILE_SERVER      = 4;ππ  MaxServers       = 8;π  DriveHandleTable = 0;π  DriveFlagTable   = 1;π  DriveServerTable = 2;π  ServerMapTable   = 3;π  ServerNameTable  = 4;ππTYPEπ  Buf32 = ARRAY [0..31] OF BYTE;π  Buf16 = ARRAY [0..15] OF BYTE;π  Buf8  = ARRAY [0..7]  OF BYTE;π  Buf4  = ARRAY [0..3]  OF BYTE;ππCONSTπ  EncryptTable : ARRAY [BYTE] OF BYTE =π($7,$8,$0,$8,$6,$4,$E,$4,$5,$C,$1,$7,$B,$F,$A,$8,π $F,$8,$C,$C,$9,$4,$1,$E,$4,$6,$2,$4,$0,$A,$B,$9,π $2,$F,$B,$1,$D,$2,$1,$9,$5,$E,$7,$0,$0,$2,$6,$6,π $0,$7,$3,$8,$2,$9,$3,$F,$7,$F,$C,$F,$6,$4,$A,$0,π $2,$3,$A,$B,$D,$8,$3,$A,$1,$7,$C,$F,$1,$8,$9,$D,π $9,$1,$9,$4,$E,$4,$C,$5,$5,$C,$8,$B,$2,$3,$9,$E,π $7,$7,$6,$9,$E,$F,$C,$8,$D,$1,$A,$6,$E,$D,$0,$7,π $7,$A,$0,$1,$F,$5,$4,$B,$7,$B,$E,$C,$9,$5,$D,$1,π $B,$D,$1,$3,$5,$D,$E,$6,$3,$0,$B,$B,$F,$3,$6,$4,π $9,$D,$A,$3,$1,$4,$9,$4,$8,$3,$B,$E,$5,$0,$5,$2,π $C,$B,$D,$5,$D,$5,$D,$2,$D,$9,$A,$C,$A,$0,$B,$3,π $5,$3,$6,$9,$5,$1,$E,$E,$0,$E,$8,$2,$D,$2,$2,$0,π $4,$F,$8,$5,$9,$6,$8,$6,$B,$A,$B,$F,$0,$7,$2,$8,π $C,$7,$3,$A,$1,$4,$2,$5,$F,$7,$A,$C,$E,$5,$9,$3,π $E,$7,$1,$2,$E,$1,$F,$4,$A,$6,$C,$6,$F,$4,$3,$0,π $C,$0,$3,$6,$F,$8,$7,$B,$2,$D,$C,$6,$A,$A,$8,$D);ππ  EncryptKeys : Buf32 =π($48,$93,$46,$67,$98,$3D,$E6,$8D,$B7,$10,$7A,$26,$5A,$B9,$B1,$35,π $6B,$0F,$D5,$70,$AE,$FB,$AD,$11,$F4,$47,$DC,$A7,$EC,$CF,$50,$C0);πππTYPEπ  WORD   = INTEGER;ππ  NetStr = STRING[47];π  GenStr = STRING[128];π  FourBytes = ARRAY [1..4] of BYTE;π  MemBlock = ARRAY [1..128] OF CHAR;ππ{  RegsType = RECORD case integer ofπ    1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : INTEGER);π    2: (AL, AH, BL, BH, CL, CH, DL, DH            : BYTE);π    END; }ππ  ServerItem = ARRAY [1..48] OF CHAR;π  ServerName = ARRAY[1..MaxServers] OF ServerItem;π  ServerNamePtr = ^ServerName;ππ  ServerMappingEntry = RECORDπ    SlotInUse      : BYTE;π    OrderNumber    : BYTE;π    ServerNet      : ARRAY [1..10] OF CHAR;π    ServerSocket   : WORD;π    RouterNet      : ARRAY [1..10] OF CHAR;π    RouterSocket   : WORD;π    ShellInternal  : ARRAY [1..6] OF CHAR;π  END;ππ  ServerMappingTable = ARRAY [1..MaxServers] OF ServerMappingEntry;π  ServerMappingPtr   = ^ServerMappingTable;ππVARπ  rc   : BYTE;π  Regs : Registers;π  { Regs : RegsType; }ππ{ -------------------------------------------------------------- }ππFUNCTION GetString(VAR NameEntry: ServerItem): GenStr;πVAR   tmp: GenStr;π      i:   INTEGER;π      ct:  BYTE;πBEGINπ  i  := 1;π  ct := 0;ππ  WHILE NameEntry[i] <> CHR(0) DOπ     BEGINπ       tmp[i] := NameEntry[i];π       i  := i  + 1;π       ct := ct + 1;π       END;ππ  tmp[0] := CHAR(ct);π  GetString := tmp;π  END;ππPROCEDURE Str2Az(st: GenStr; VAR az; size: INTEGER);πVAR  p: ^BYTE;πBEGINπ  Fillchar(az, size+1, 0);π  p := ADDR(st[1]);π  Move(p^, az, size);π  END;ππPROCEDURE DefaultRegs(VAR r: Registers);πBEGINπ  r.DS := DSeg;π  r.ES := DSeg;π{ r.AX := 0;π  r.BX := 0;π  r.CX := 0;π  r.DX := 0;π  r.BP := 0;π  r.SI := 0;π  r.DI := 0; }π  END;ππFUNCTION FileServiceRequest( func:            BYTE;π                             VAR q; qlen:     WORD;π                             VAR reply; rlen: WORD): BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.DS := Seg(q);π  Regs.SI := Ofs(q);π  Regs.CX := qlen;π  Regs.ES := Seg(reply);π  Regs.DI := Ofs(reply);π  Regs.DX := rlen;π  Regs.AH := $F2;π  Regs.AL := func;π  MSDOS(Regs);π  FileServiceRequest := Regs.AL;πEND;ππFUNCTION CallNetware(RegAH : BYTE; VAR request, reply): BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.AH := RegAH;π  Regs.DS := Seg(request);π  Regs.SI := Ofs(request);π  Regs.ES := Seg(reply);π  Regs.DI := Ofs(reply);π  MSDOS(Regs);π  CallNetware := Regs.AL;π  END;ππPROCEDURE UpcaseStr(VAR s: GenStr);πVAR  i : INTEGER;πBEGINπ  for i := 1 to Length(s) doπ    Beginπ    s[i] := UpCase(s[i]);π    End;π  END;ππFUNCTION GetServerMappingPtr : ServerMappingPtr;πVAR TmpPtr: ServerMappingPtr;πBEGINπ  DefaultRegs(Regs);π  Regs.AX := $EF03;π  MSDOS(Regs);π  TmpPtr  := Ptr(Regs.ES, Regs.SI);π  GetServerMappingPtr := TmpPtr;π  END;ππFUNCTION GetServerNamePtr : ServerNamePtr;πVAR TmpPtr: ServerNamePtr;πBEGINπ  DefaultRegs(Regs);π  Regs.AX := $EF04;π  MSDOS(Regs);π  TmpPtr  := Ptr(Regs.ES, Regs.SI);π  GetServerNamePtr := TmpPtr;π  END;ππFUNCTION GetServerNumber(s: NetStr): BYTE;πVARπ  t : ServerNamePtr;π  m : ServerMappingPtr;π  i : INTEGER;πBEGINπ  m := GetServerMappingPtr;π  t := GetServerNamePtr;π  UpCaseStr(s);ππ  FOR i:=1 TO MaxServers DO BEGINπ    IF (m^[i].SlotInUse = $FF) AND (GetString(t^[i]) = s) THEN BEGINπ      GetServerNumber := i;π      Exit;π    END;π  END;π  GetServerNumber := 0;πEND;ππFUNCTION ReadPropertyValue(ObjectType : WORD; ObjectName : NetStr;π                        Segnr : BYTE; Property : NetStr;π                        VAR item): BYTE;πVARπ  req : RECORDπ    plen : WORD;π    func : BYTE;π    otype : WORD;π    Filler : GenStr;π  END;π  rep : RECORDπ    plen : WORD;π    Data : ARRAY [1..128] OF BYTE;π    More : BYTE;π    PropFlags : BYTE;π  END;ππBEGINπ  req.func := 61;π  req.otype := Swap(ObjectType);π  req.plen := Length(ObjectName) +π              Length(Property) + 6;π  req.filler := ObjectName + Char(Segnr) +π                Char(Length(Property)) +π                Property;π  req.filler[0] := Char(Length(ObjectName));π  rep.plen := SizeOf(rep) - 2;π  ReadPropertyValue := CallNetware($E3,req,rep);π  Move(rep.data, item, SizeOf(rep.data) + 2);πEND;ππFUNCTION InsertServer(Name : NetStr):BYTE;πVARπ  MapPtr  : ServerMappingPtr;π  NamePtr : ServerNamePtr;π  res     : BYTE;π  free,i  : INTEGER;π  data    : ARRAY [1..130] OF BYTE;ππ  FUNCTION LowerAddr(VAR a, b): BOOLEAN;π  TYPEπ    Net_Address = ARRAY [1..10] OF CHAR;π  VARπ    a_addr : Net_Address ABSOLUTE a;π    b_addr : Net_Address ABSOLUTE b;π  BEGINπ    LowerAddr := a_addr < b_addr;π  END;ππBEGINπ  UpCaseStr(Name);π  IF GetServerNumber(Name) <> 0 THEN BEGINπ    InsertServer := 0;π    Exit;π  END;ππ  res := ReadPropertyValue(FILE_SERVER, name, 1, 'NET_ADDRESS', data);π  IF res <> 0 THEN BEGINπ    InsertServer := $7D;π    Exit;π  END;ππ  MapPtr := GetServerMappingPtr;π  free := 1;π  WHILE (MapPtr^[free].SlotInUse = $FF) DO BEGINπ    free := free + 1;π    IF free > MaxServers THEN BEGINπ      InsertServer := $7C;π      Exit;π    END;π  END;ππ  NamePtr := GetServerNamePtr;π  WITH MapPtr^[free] DO BEGINπ    Move(data, ServerNet, 12);π    Str2Az(name, NamePtr^[free], SizeOf(NamePtr^[free]));π    OrderNumber := 1;π    FOR i := 1 TO MaxServers DO BEGINπ      IF MapPtr^[i].SlotInUse = $FF THEN BEGINπ        IF LowerAddr(MapPtr^[i].ServerNet, ServerNet) THENπ          OrderNumber := OrderNumber + 1π        ELSEπ          MapPtr^[i].OrderNumber := MapPtr^[i].OrderNumber + 1;π      END;π    END;π    SlotInUse := $FF;π  END;π  InsertServer := 0;πEND;ππFUNCTION AttachServerNumber(func : BYTE; sn : BYTE) : BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.ah := $F1;π  Regs.al := func;π  Regs.dl := sn;π  MSDOS(Regs);π  AttachServerNumber := Regs.al;πEND;ππFUNCTION AttachServer(func : BYTE; name : NetStr) : BYTE;πVARπ  sn : BYTE;πBEGINπ  sn := GetServerNumber(name);π  IF sn = 0 THEN BEGINπ    AttachServer := $7B;π    Exit;π  END;π  AttachServer := AttachServerNumber(func,sn);πEND;πππFUNCTION GetEffectiveServer:BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.ax := $F002;π  MSDOS(Regs);π  GetEffectiveServer := Regs.al;πEND;ππPROCEDURE SetPrimaryServer(sno:BYTE);πBEGINπ  DefaultRegs(Regs);π  Regs.ax := $F004;π  Regs.dl := sno;π  MSDOS(Regs);πEND;ππFUNCTION GetPrimaryServer:BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.ax := $F005;π  MSDOS(Regs);π  GetPrimaryServer := Regs.al;πEND;ππFUNCTION SetPreferredServer(sno: BYTE): BYTE;πBEGINπ  DefaultRegs(Regs);π  Regs.ax := $F000;π  Regs.dl := sno;π  MSDOS(Regs);π  Regs.ax := $F001;π  MSDOS(Regs);π  SetPreferredServer := Regs.AL;πEND;ππFUNCTION MapNameToNumber(ObjectType : WORD;ObjectName : NetStr;π                         VAR ObjectID : FourBytes): BYTE;πVARπ  req : RECORDπ    plen : WORD;π    func : BYTE;π    otype : WORD;π    name : NetStr;π  END;π  rep : RECORDπ    plen : WORD;π    objID : FourBytes;π    otype : WORD;π    name : ARRAY [1..48] OF CHAR;π  END;πBEGINπ  req.func := 53;      {Get an object's number}π  req.otype := Swap(ObjectType);π  req.name := ObjectName;π  req.plen := Length(ObjectName) + 4;π  rep.plen := SizeOf(rep) - 2;π  MapNameToNumber := CallNetware($E3, req, rep);π  ObjectID := rep.objID;πEND;ππFUNCTION MapNumberToName(ID : FourBytes; VAR Name; VAR Otype : WORD):BYTE;πVARπ  req : RECORDπ    plen : WORD;π    func : BYTE;π    OID  : FourBytes;π  END;π  rep : RECORDπ    plen  : WORD;π    OID   : FourBytes;π    otyp  : WORD;π    Oname : ServerItem;π  END;π  nam : NetStr ABSOLUTE Name;πBEGINπ  req.func := 54;      {Get an object's name}π  req.OID := ID;π  req.plen := SizeOf(req) - 2;π  rep.plen := SizeOf(rep) - 2;π  MapNumberToName := CallNetware($E3,req,rep);π  Nam := GetString(rep.OName);π  Otype:= Swap(rep.Otyp);πEND;ππFUNCTION LoginAnObject( Name:NetStr; Otype:WORD; Passw: NetStr):BYTE;πVARπ  req : RECORDπ    plen : WORD;π    func : BYTE;π    otype : WORD;π    NamePass : STRING[96];π  END;π  rep : RECORDπ    plen : WORD;π  END;πBEGINπ  req.plen := 5 + Length(Name) + Length(Passw);π  req.func := 20;π  UpCaseStr(Passw);π  UpCaseStr(Name);π  req.otype := Swap(otype);π  req.NamePass:=Name;π  Move(Passw, req.NamePass[Length(Name)+1], Length(Passw) + 1);π  rep.plen := 0;π  LoginAnObject := CallNetware($E3, req, rep);πEND;ππFUNCTION LoginUser(Name, Password: NetStr): BYTE;πVARπ  req : RECORDπ    plen : INTEGER;π    func : BYTE;π    NamePass : STRING[96];π  END;π  rep : RECORDπ    plen : INTEGER;π  END;ππBEGINπ  req.plen := 3 + Length(Name) + Length(Password);π  req.func := 0;π  UpcaseStr(Password);π  UpcaseStr(Name);π  req.NamePass := Name;π  Move(Password, req.NamePass[Length(Name)+1], Length(Password)+1);π  rep.plen := 0;π  LoginUser := CallNetware($E3, req, rep);πEND;ππFUNCTION GetEncryptionKey(VAR key : Buf8): BYTE;πVARπ  q : RECORDπ    plen : WORD;π    func : BYTE;π  END;πBEGINπ  q.plen := 1;π  q.func := $17;π  GetEncryptionKey := FileServiceRequest($17, q, SizeOf(q), key, SizeOf(key));πEND;ππFUNCTION LoginEncrypted(name : NetStr; otype : WORD; VAR key : Buf8): BYTE;πVARπ  a : RECORDπ    plen : WORD;π    func : BYTE;π    key  : Buf8;π    otyp : WORD;π    name : NetStr;π  END;πBEGINπ  a.plen := Length(name) + 12;π  a.func := $18;π  a.key  := key;π  a.otyp := Swap(otype);π  a.name := name;π  LoginEncrypted := FileServiceRequest($17, a, Length(name)+14, Mem[0:0], 0);πEND;ππPROCEDURE Shuffle1(VAR temp : Buf32; VAR target);πVARπ  t  :  Buf16 ABSOLUTE target;π  b4 :  WORD;π  b3 :  BYTE;π  s, d, b2, i : WORD;πBEGINπ  b4 := 0;π  FOR b2 := 0 TO 1 DO BEGINπ    FOR s := 0 TO 31 DO BEGINπ      b3 := Lo(Lo(temp[s] + b4)π            XOR Lo(temp[(s + b4) AND 31]π          - EncryptKeys[s]));π      b4 := b4 + b3;π      temp[s] := b3;π    END;π  END;ππ  FOR i := 0 TO 15 DOπ    t[i] := EncryptTable[temp[i Shl 1]]π        OR (EncryptTable[temp[i Shl 1 +1]] Shl 4);πEND;ππPROCEDURE Shuffle(VAR lon, buf; buflen : WORD; VAR target);πVARπ  l : Buf4 ABSOLUTE lon;π  b : ARRAY [0..127] OF BYTE ABSOLUTE buf;π  b2 : WORD;π  temp : Buf32;π  s, d : WORD;πBEGINπ  IF buflen > 0 THENπ     WHILE (buflen > 0) AND (b[buflen-1] = 0) DOπ       buflen := buflen - 1;ππ  FillChar(temp, SizeOf(temp), #0);ππ  d := 0;π  WHILE buflen >= 32 DO BEGINπ    FOR s := 0 TO 31 DO BEGINπ      temp[s] := temp[s] XOR b[d];π      d := d + 1;π    END;π    buflen := buflen - 32;π  END;π  b2 := d;ππ  IF buflen > 0 THEN BEGINπ    FOR s := 0 TO 31 DO BEGINπ      IF d + buflen = b2 THEN BEGINπ        b2 := d;π        temp[s] := temp[s] XOR EncryptKeys[s];π      ENDπ      ELSE BEGINπ        temp[s] := temp[s] XOR b[b2];π        b2 := b2 + 1;π      END;π    END;π  END;π  FOR s := 0 TO 31 DOπ    temp[s] := temp[s] XOR l[s AND 3];ππ  Shuffle1(temp, target);πEND;ππPROCEDURE Encrypt(VAR fra, buf, til);πVARπ  f : Buf8  ABSOLUTE fra;π  t : Buf8  ABSOLUTE til;π  k : Buf32;π  s : WORD;πBEGINπ  Shuffle(f[0], buf, 16, k[0]);π  Shuffle(f[4], buf, 16, k[16]);π  FOR s := 0 TO 15 DOπ    k[s] := k[s] XOR k[31-s];π  FOR s := 0 TO 7 DOπ    t[s] := k[s] XOR k[15-s];πEND;ππFUNCTION LoginToFileServer(name: NetStr; otype: WORD; passw: GenStr): BYTE;πVARπ  key : Buf8;π  id  : FourBytes;π  buf : Buf32;π  res : BYTE;ππBEGINπ  UpCaseStr(passw);π  res := GetEncryptionKey(key);π  IF res = 0 THEN BEGINπ    res := MapNameToNumber(otype, name, id);π    IF res = 0 THEN BEGINπ      Shuffle(id, passw[1], Length(passw), buf);π      Encrypt(key, buf, key);π      res := LoginEncrypted(name, otype, key);π    END;π  ENDπ  ELSE BEGINπ    res := LoginAnObject(name, otype, passw);π    END;ππ  LoginToFileServer := res;πEND;ππFUNCTION Login(Sname, OName : NetStr; OType : WORD; Passw : NetStr) : BYTE;πVARπ  sn, res, rc : BYTE;π  Curr_Server : BYTE;πBEGINπ  UpCaseStr(SName);π  sn := GetServerNumber(Sname);ππ  IF sn = 0 THEN BEGINπ    res := InsertServer(SName);π    IF res <> 0 THEN BEGINπ      Login := res;π      Exit;π    END;π    sn := GetServerNumber(SName);π  END;ππ  res := AttachServerNumber(0, sn);π  IF res <> 0 THEN BEGINπ    Login := res;π    Exit;π  END;ππ  Curr_Server := GetEffectiveServer;π  IF SetPreferredServer(sn) = sn THENπ    rc := LoginToFileServer(OName, Otype, Passw)π  ELSEπ    rc := $7A;ππ  res := SetPreferredServer(Curr_Server);π  Login := rc;πEND;ππBEGINπ  IF ParamCount <> 3 THEN BEGINπ     Writeln('Please supply server name, your user id, and a password.');π     Exit;π     END;ππ  rc := Login(ParamStr(1), ParamStr(2), NET_USER, ParamStr(3));ππ  IF rc <> 0 THEN BEGINπ     Writeln('Login failed.');π     Exit;π     END;ππ  END.ππ                            2      08-24-9413:49ALL                      NORBERT IGL              Encryped logins          SWAG9408    äf
  2. ╓    23     ,î   {π SM> Have you got any idea on how to do a login under Novell 3.11+?ππ SM> I have some source (SWAG has source for a great TPU), butπ SM> unfortunatly it doesn't do encrypted logins.. I managed to findπ SM> *some* reference to it in the interrupt list (int 21h, the F2hπ SM> multiplexor functions 17h/18h), but it didn't give any details onπ SM> how this is done...ππ hmmm. Novell never released any informations about Password Encrytion !ππ You got two choices (:-)ππ1.   do a "Set Allow Unencrypted Passwords = ON" on the server console,π     use the following, ripped from an old src "Novapi.zip:Novell.pas"ππ------------------------------------------------------------------------}πuses dos;π[...]ππ{ obj_type:   User = 1, group =2 printserver = 3 }ππprocedure login_to_file_server( obj_type:integer;π                              _name,π                              _password : string;π                          var retcode:integer);πvarπ      regs : registers;ππ      request_buffer : recordπ            B_length : integer;π         subfunction : byte;π              o_type : packed array [1..2] of byte;π         name_length : byte;π            obj_name : packed array [1..47] of byte;π     password_length : byte;π            password : packed array [1..27] of byte;π                 end;ππ        reply_buffer : recordπ            R_length : integer;π                 end;ππ               count : integer;ππbeginπWith request_buffer doπbeginπ B_length := 79;π subfunction := $14;π o_type[1] := 0;π o_type[2] := obj_type;π for count := 1 to 47 do obj_name[count] := $0;π for count := 1 to 27 do password[count] := $0;π if length(_name) > 0 thenπ    for count := 1 to length(_name) doπobj_name[count]:=ord(upcase(_name[count]));π if length(_password) > 0 thenπ    for count := 1 to length(_password) doπpassword[count]:=ord(upcase(_password[count]));π {set to full length of field}π name_length := 47;π password_length := 27;πend;πWith reply_buffer doπbeginπ R_length := 0;πend;π  With Regs Do Beginπ    Ah := $e3;                 { moved to $F2 for v3.x ??? }π    Ds := Seg(Request_Buffer);π    Si := Ofs(Request_Buffer);π    Es := Seg(reply_buffer);π    Di := Ofs(reply_buffer);π  End;π  MsDos(Regs);π  retcode := regs.alπend;ππprocedure logout;π{logout from all file servers}πvar regs : registers;πbeginπ regs.ah := $D7;π msdos(regs);πend;ππprocedure logout_from_file_server(var id: integer);π{logout from one file server}πvar regs : registers;πbeginπ regs.ah := $F1;π regs.al := $02;π regs.dl := id;π msdos(regs);πend;ππ------------------------------------------------------------------------ππ2.   get a copy of "Charles Rose: Netware Programming". There are someπ     <obj> for "C", and in my German version  TPU's for Turbo/BP" !ππ                                                                     3      08-24-9413:49ALL                      KLAUS WIEGAND            Network Options          SWAG9408    èm'ë    51     ,î   {π> I'm looking for information and or code (pascal pref) on the theπ> following network options:π>π> 1.  A routine to determine if Novel IPX is available (active/loaded)}ππ(*--------------------------------------------------------------------------*)π(*           IsNovellActive  --- Checks if Novell network is active         *)π(*--------------------------------------------------------------------------*)ππFUNCTION IsNovellActive : BOOLEAN;ππ(*--------------------------------------------------------------------------*)π(*                                                                          *)π(*    Function: IsNovellActive                                              *)π(*                                                                          *)π(*    Purpose:  Checks if Novell network active                             *)π(*                                                                          *)π(*    Calling Sequence:                                                     *)π(*                                                                          *)π(*       Novell_On := IsNovellActive : BOOLEAN;                             *)π(*                                                                          *)π(*          Novell_On --- TRUE if Novell network is active.                 *)π(*                                                                          *)π(*    Calls:  MsDos                                                         *)π(*                                                                          *)π(*--------------------------------------------------------------------------*)ππVARπ   Regs : Registers;ππBEGIN (* IsNovellActive *)ππ   Regs.CX := 0;π   Regs.AL := 0;π                                   (* Request workstation ID.          *)π                                   (* This should be ignored if Novell *)π                                   (* network software isn't active.   *)π   Regs.AH := $DC;ππ   MsDos( Regs );π                                   (* If we got back a non-zero station *)π                                   (* ID, then Novell must be loaded.   *)ππ   IsNovellActive := ( Regs.AL <> 0 );ππEND   (* IsNovellActive *);πππ(* ************** second method ******************** *)ππuses  dos ;πvar   Regs : registers ;π      ReplyBuffer : array[1..40] of char ;πππfunction IPX_Loaded:boolean;πbeginπ   Regs.AX := $7A00 ;π   intr($2F,Regs) ;π   IPX_Loaded := (Regs.AL = $FF)πend;ππfunction Netbios_Loaded:Boolean;πbeginπ Regs.AH := $35; (* DOS function that checks an interrupt vector *)π Regs.AL := $5C; (* Interrupt vector to be checked *)π NetBios_Installed := True;π msdos(Regs) ;π if ((Regs.ES = 0) or (Regs.ES = $F000))π   then  NetBios_Installed := Falseπend;πππfunction NetShell_Installed:Boolean;πbeginπ   with Regs do beginπ      AH := $EA ;π      AL := 1 ;π      BX := 0 ;π      ES := seg(ReplyBuffer) ;π      DI := ofs(ReplyBuffer) ;π   end ; (* with do begin *)π   msdos(regs) ;π   NetShell_Installed := (Regs.BX = 0)πend.π{π> 3.  I'm looking for any available NetBIOS-compatible routines whichπ>     will yield a "connection number" (not a username or node id).  I'mπ>     under the impression that this ability is not available via NetBIOS.π>     Is this true?π}ππuses dos;πtypeππ  DayOfTheWeek     = (Sunday,Monday,Tuesday,Wednesday,Thursday,π                      Friday,Saturday);π  NovDateType      = recordπ                       Year,                     {80=1980}π                       Month,π                       Day,π                       Hour,π                       Minute,π                       Second     : Byte;π                       WeekDay    : DayOfTheWeek;π                       Filler     : Byte;    {!!.03}π                     end;π  ConnInfoType     = recordπ                       ObjectID   : LongInt;     {the logged in object's ID}π                       ObjectType : Word;        {the logged object's type}π                       ObjectName : String[48];  {the name of the object}π                       LoginDate  : NovDateType; {the time/date the object}π                                                 {logged on to connection}π                     end;ππfunction NetWareSwapLong(L : LongInt) : LongInt;πInline(π  $5A/                   {  pop    dx}π  $86/$D6/               {  xchg   dh,dl}π  $58/                   {  pop    ax}π  $86/$C4);              {  xchg   ah,al}ππfunction AsciiZ2Str(var Buffer; Max : Byte) : String;πconstπ  AsciiZMAX        = 255;ππtypeπ  AsciiZBuffer     = Array[1..AsciiZMAX] of Char;ππvarπ  A                : AsciiZBuffer absolute Buffer;π  I                : Word;π  S                : String;ππbeginπ  I := 1;π  { search for terminating #0, stop if max string length exceeded}π  while (A[I] <> #0) and (I < Max) do beginπ    S[I] := A[I];π    Inc(I);π  end;π  S[0] := Char(I-1);π  AsciiZ2Str := S  {return the string}πend;ππππfunction GetConnNo : Byte;πvarπ  Regs          : dos.Registers;πbeginπ  regs.AX := $DC00;π  intr($21,Regs);π  GetConnNo := Regs.ALπend;πprocedure GetConnInfo(ConnNo : Byte; var ConnInfo : ConnInfoType);πvarπ  Regs          : dos.Registers;π  Request          : recordπ                       Len     : Word;π                       SubF    : Byte;π                       Conn    : Byte;π                     end;π  Reply            : recordπ                       Len     : Word;π                       ID      : LongInt;π                       ObjType : Word;π                       ObjName : Array[1..48] of Char;π                       Time    : NovDateType;π                     end;πbeginπ  Reply.Len := SizeOf(Reply) - 2;      {!!.03}π    Request.Len  := 2;π    Request.SubF := $16;π    Request.Conn := ConnNo;π    Regs.AH := $E3;π    Regs.DS := Seg(Request);  {DS:SI points to request}π    Regs.SI := Ofs(Request);π    Regs.ES := Seg(Reply);    {ES:DI points to reply}π    Regs.DI := Ofs(Reply);π    intr($21,Regs);π  with ConnInfo do beginπ    ObjectID := NetWareSwapLong(Reply.ID);π    ObjectType  := Swap(Reply.ObjType);π    ObjectName  := AsciiZ2Str(Reply.ObjName,48);π    LoginDate   := Reply.Time;π  end;πend;ππvarπConnInfo: ConnInfoType;ππbeginπ GetConnInfo(GetConnNo,ConnInfo);π with ConnInfo doπ beginπ WriteLn('ID:   ',ObjectId);π WriteLn('Type: ',ObjectType);π WriteLn('Name: ',ObjectName);π WriteLn('Time: ',Logindate.hour:2,':',Logindate.second);π end;πend.π                                 4      08-25-9409:04ALL                      ROBIN BOWES              Call NETAPI.DLL function SWAG9408    ┴╒r₧    32     ,î   (*πFrom: ROBIN@plato.ucsalf.ac.uk (Robin Bowes)ππI'm trying to call a function in a Windows .dll fromπTurbo Pascal for Windows v1.5.ππThe .dll in question is NETAPI.DLL.  The function I want to call isπdefined as follows (in C format):ππ(from Microsoft LAN Manager Programmer's Reference, )ππNetWkstaGetInfo ( const char far *  pszServer,π       short      sLevel,π       char far *    pbBuffer,π       unsigned short   cbBuffer,π       unsigned short far * pcbTotalAvailπ      );ππwhereππpszServerπ contains the name of the server on which to execute NetWkstGetInfo.ππsLevelπ specfies the level of detail to be supplied in the return bufferππpbBufferπ points to the buffer in which data is returnedππcbBufferπ specifies the size of the buffer pointed to by pbBufferππpcbTotalAvailπ points to an unsigned integer in which the number of bytes ofπ information available is returned.πππThe detail level I require is 10 which means that the buffer returnedπwill contain a wksta_info_10 structure which is defined as follows:ππstruct wksta_info_10 {π char far *  wki10_computername;π char far *  wki10_username;π char far *  wki10_langroup;π unsigned char wki10_ver_major;π unsigned char wki10_ver_minor;π char far *  wki10_logon_domain;π char far *  wki10_oth_domains;π};πππI am having trouble getting this function to work.  It will be a .dllπeventually but for now I'm jsut coding it as a program using WinCrt.ππMy code so far looks something like this:π*)πprogram Username;ππuses WinTypes, WinCrt;ππconstπ NERR_BufTooSmall = 2123;π  NERR_Success   = 0;ππtypeπ Wksta_info_10 =π  recordπ   wki10_computername : pChar;π   wki10_username   : pChar;π   wki10_langroup   : pChar;π   wki10_ver_major   : Byte;π   wki10_ver_minor   : Byte;π   wki10_logon_domain : pChar;π   wki10_oth_domains  : pChar;π  end;π pWksta_info_10 = ^Wksta_info_10;ππfunction NetWkstaGetInfo( pszServer     : pChar;π             sLevel      : Integer;π             var pbBuffer   : pWksta_info_10;π             cbBuffer     : Word;π             var pcbTotalAvail : pWordπ            ) : Integer; far; external 'NETAPI';ππfunction getUsername(var Username : pChar) : Integer;πvarπ pWI        : pWksta_info_10;π sWorkStationInfo : Word;π pbBufLen     : pWord;π pbTotalAvail   : pWord;π uRetCode     : Integer;ππbeginπ {first call will fail but should return the size of theπ buffer needed to hold all the available data}π getMem(pbBufLen, sizeOf(pbBufLen));π  pwI := nil;π uRetCode := NetWkstaGetInfo(nil,   {Servername (nil -> local machine)}π               10,    {Reporting level}    π               pWI,   {target buffer for info}π               0,    {Size of target buffer}π               pbBufLen {Count of bytes available}π               );π {check the return code from the function}π if (uRetCode = NERR_BufTooSmall) thenπ  { check available memory }π  beginπ  if maxAvail < pbBufLen^ thenπ   beginπ   getUsername := -1;π      Exitπ   endπ    elseπ   {allocate memory for buffer to hold information}π   beginπ   getMem(pWI, pbBufLen^)π   endπ  endπ elseπ   {Unexpected error returned}π  beginπ    {Pass return code back to calling program}π  getUsername := uRetCode;π  Exitπ  end;ππ {second call to get information}π getMem(pbTotalAvail, sizeOf(pbTotalAvail));π uRetCode := NetWkstaGetInfo(nil, 10, pWI,  pbBufLen^, pbTotalAvail);π getUsername := uRetCode;π if uRetCode = NERR_Success thenπ   beginπ  Username := pWI^.wki10_username;π  end;π freeMem(pbBufLen, sizeOf(pbBufLen));π freeMem(pbTotalAvail, sizeOf(pbTotalAvail))πend;ππ{exportsπ getUsername  index 1;}ππvarπ retVal : Integer;π uName : pChar;ππbeginπgetMem(uName, sizeOf(uName));πretVal := getUserName(uName);πif retVal = NERR_Success thenπ writeln(uName)πelseπ writeln('Error returned: ', retVal);πfreeMem(uName, sizeOf(uName));πend.π{ππThis compiles OK but throws a GPF in NETAPI.DLL.ππI'm fairly sure it's the conversion of the structure type that's causingπthe problem.ππHas anybody got any ideas ?ππ}                            5      08-25-9409:09ALL                      MICHAEL HOENIE           Networking               SWAG9408    MF²º    64     ,î   {πI'm still looking for help with these networking routines. I've revisedπthem again to make a full standing unit. This NETWORK unit will compileπstand-alone with TP 6.0. I still get an error 162 when using theseπroutines, which from the manual says MACHINE FAILURE or hardware. I haveπrun it on at least 10 different machines and get the same problem.ππIf *ANYONE* has a better way of keeping another node from accessing aπfile, please, PLEASE let me know! I have an ENTIRE project (10,000+πlines) on hold until I get these networking routines done.π}π  UNIT NETWORK;ππ  interface uses dos;ππ  constπ    max_timeout=10; { seconds to time out on network timeout }π    max_nodes=25;ππ  typeπ    string80=string[80];π    networkrecord=record { basic makeup of the actual user }π      x_username:string[5];           { network name of user }π      x_active:boolean;               { * IMPORTANT * : if node is active }π    end;ππ  varπ    netfile:file of networkrecord;π    netdata:networkrecord;π    network_node:integer;π    time1,time2,time3,date1,date2,date3:string[15];π    incom,incom1,out,out1:string[255];π    _retval:integer;π    _retbol:boolean;ππ    function  network_exist(filename1:string80):byte;π    procedure node_status(filename1:string80);π    procedure lock_file(filename2:string80);π    procedure unlock_file(filename3:string80);π    procedure make_nodes;π    procedure update_node;π    procedure log_node;π    procedure log_off_node;ππ  implementationππ(*═════════════════════════════════════════════════════════════════════════*)ππ   procedure timedate;π   varπ     ax1,ax2,ax3,ax4:word;π     year,month,mil,day,hour,hour1,minute,second:string[20];π   beginπ     time1:=''; { 22:00:00 }π     date1:=''; { 03/03/88 }π     time2:=''; { 02:03am  }π     time3:=''; { 00:00 }π     date2:=''; { wednesday, january 25th, 1988 }π     gettime(ax1,{ hour } ax2,{ minute } ax3, { second }ax4); { milli-second }π     str(ax1,hour);π     if ax1<=12 then str(ax1,hour1) else str(ax1-12,hour1);π     if length(hour1)=1 then insert('0',hour1,1);π     str(ax2,minute);π     str(ax3,second);π     if length(minute)=1 then insert('0',minute,1);π     if length(second)=1 then insert('0',second,1);π     if length(hour)=1 then insert('0',hour,1);π     time1:=hour+':'+minute+':'+second;π     case ax1 ofπ       0..11:out1:='AM'π         else out1:='PM';π     end;π     time2:=hour1+':'+minute+' '+out1;π     time3:=hour1+':'+minute;π     getdate(ax1, { year  }ax2, { month }ax3, { day }ax4);{ day of week }π     str(ax3,day);π     if length(day)=1 then insert('0',day,1);π     str(ax1,year);π     str(ax2,month);π     if length(month)=1 then insert('0',month,1);π     date1:=month+'-'+day+'-'+copy(year,3,2);π   end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    function network_exist(filename1:string80):byte;π    varπ      net_file:file;π    beginπ      network_exist:=$0;π      assign(net_file,filename1);π      {$i-} reset(net_file) {$i+};π      case ioresult ofπ        0:close(net_file);π        1:network_exist:=$1; { nothing }π        2:network_exist:=$2; { file not found }π        5:network_exist:=$5; { access denied }π      end;π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure node_status(filename1:string80);π    varπ      do_wait:boolean;π      s_time,c_time:string[2];π      d_timeout,d_wait,d_count:integer;π      _retbyte:byte;π      erfile:text;π    beginπ      filename1:=filename1+'.lck';π      do_wait:=false;π      timedate;π      s_time:=copy(time1,7,2);π      d_wait:=0;π      d_timeout:=0;π      while not do_wait doπ        beginπ          _retbyte:=network_exist('LOCK\'+filename1);π          case _retbyte ofπ            $0:write('.');π            $5:write('.');π            $1:do_wait:=true;π            $2:do_wait:=true;π          end;π          if do_wait=true then d_timeout:=0;π          timedate;π          c_time:=copy(time1,7,2);π          if c_time<>s_time thenπ            beginπ              s_time:=c_time;π              d_count:=d_count+1;π              d_timeout:=d_timeout+1;π            end;π          if d_timeout>max_timeout thenπ            beginπ              writeln('NETWORK TIMEOUT...   NOTE_STATUS');π              halt;π            end;π        end;π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure lock_file(filename2:string80);π    varπ      fvar2:text;π    beginπ      if pos('.',filename2)>0 thenπ        delete(filename2,pos('.',filename2),length(filename2));π      filename2:=filename2+'.LCK';π      node_status(filename2);π      assign(fvar2,'LOCK\'+filename2);π      rewrite(fvar2);π      write(fvar2,'A');π      close(fvar2);π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure unlock_file(filename3:string80);π    varπ      fvar3:text;π    beginπ      if pos('.',filename3)>0 thenπ        delete(filename3,pos('.',filename3),length(filename3));π      filename3:=filename3+'.LCK';π      if network_exist('LOCK\'+filename3)=$0 thenπ        beginπ          assign(fvar3,'LOCK\'+filename3);π          erase(fvar3);π        end;π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure make_nodes;π    beginπ      case network_exist('LOCK\'+'NETWORK.SYS') ofπ        $2:beginπ             lock_file('NETWORK');π             assign(netfile,'LOCK\'+'NETWORK.SYS');π             rewrite(netfile);π             netdata.x_username:='';π             netdata.x_active:=false;π             for _retval:=0 to max_nodes doπ               beginπ                 seek(netfile,_retval);π                 write(netfile,netdata);π               end;π             close(netfile);π             unlock_file('NETWORK');π           end;π      end;π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure update_node;π    beginπ      with netdata doπ        beginπ          x_username:='MSH';π          x_active:=true;π        end;π      lock_file('NETWORK');π      assign(netfile,'LOCK\'+'NETWORK.SYS');π      {$i-} reset(netfile); {$i+}π      if ioresult>=1 thenπ        beginπ          writeln('NETWORK ERROR: UPDATE_NODE');π          halt;π        end;π      seek(netfile,network_node);π      write(netfile,netdata);π      close(netfile);π      unlock_file('NETWORK');π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure log_node;π    beginπ      network_node:=-1;π      lock_file('NETWORK');π      assign(netfile,'LOCK\'+'NETWORK.SYS');π      {$i-} reset(netfile) {$i+};π      if ioresult>=1 thenπ        beginπ          writeln('NETWORK ERROR: LOG_NODE');π          halt;π        end;π      for _retval:=filesize(netfile)-1 downto 0 doπ        beginπ          seek(netfile,_retval);π          {$i-} read(netfile,netdata); {$i+}π          if ioresult>=1 thenπ            beginπ              writeln('NETWORK ERROR: LOG_NODE');π              halt;π            end;π          if NOT netdata.x_active then network_node:=_retval;π        end;π      if network_node=-1 thenπ        beginπ          writeln('NETWORK ERROR: LOG_NODE');π          halt;π        end;π      seek(netfile,network_node);π      write(netfile,netdata);π      close(netfile);π      unlock_file('NETWORK');π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ    procedure log_off_node;π    beginπ      lock_file('NETWORK');π      assign(netfile,'LOCK\'+'NETWORK.SYS');π      {$i-} reset(netfile) {$i+};π      if ioresult>=1 thenπ        beginπ          writeln('NETWORK ERROR: LOG_OFF_NODE');π          halt;π        end;π      netdata.x_username:='';π      netdata.x_active:=false;π      seek(netfile,network_node);π      write(netfile,netdata);π      close(netfile);π      unlock_file('NETWORK');π    end;ππ(*═════════════════════════════════════════════════════════════════════════*)ππ  END.π                                                                                  6      08-25-9409:10ALL                      KEVIN R. PIERCE          Novell Reading           SWAG9408    Añ╡    18     ,î   Unit Litl_Nov;ππ(**********************************************************************)π(*    by Kevin R. Pierce                                              *)π(*       December 29, 1991                                            *)π(*    Kev1n@aol.com                                                   *)π(**********************************************************************)πinterfaceππtypeπ  LoginTime    = array[0..6] of byte;ππ  ConnectionInfo = recordπ                     Object_ID   : longint;π                     Object_Type : word;π                     Object_Name : array[1..48] of char;π                     Login_Time  : LoginTime;π                     ApplicationNumber     : word;    {swap & display Hex}π                   end;ππ  CnxnInfoREQUEST = recordπ                      ReqBuffLen : word;  {always = 2}π                      Mask       : byte;  {always = 16h}π                      CnxnNo     : byte;  { >1 }π                    end;ππ  CnxnInfoREPLY = recordπ                    RepBuffLen : word;  {always = SIZEOF(ConnectionInfo) }π                    Data       : ConnectionInfo;π                  end;πππfunction  NOV_GetConnectionNumber:integer;πprocedure NOV_GetConnectionInformation(connection:byte; varπResult:ConnectionInfo);ππ(**********************************************************************)πimplementationππusesπ  dos;ππfunction NOV_GetConnectionNumber:integer;π  varπ    buf : registers;π  beginπ    buf.AH:=$DC;π    intr($21,buf);π    NOV_GetConnectionNumber:=buf.AL;π  end;ππprocedure NOV_GetConnectionInformation(connection:byte; varπResult:ConnectionInfo);π  varπ    buf : registers;π    req : CnxnInfoREQUEST;π    rep : CnxnInfoREPLY;π  beginπ    with buf doπ      beginπ        AH:=$E3;π        DS:=seg(req);π        SI:=ofs(req);π        ES:=seg(rep);π        DI:=ofs(rep);π      end;π    with req doπ      beginπ        ReqBuffLen := Sizeof(req)-2;π        Mask       := $16;π        CnxnNo     := Connection;π      end;π    fillchar(rep,sizeof(rep),0);π    rep.RepBuffLen:=Sizeof(rep)-2;π    intr($21,buf);π    Result:=rep.data;π  end;ππend.πππ